package com.mm.util.quartz;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mm.base.quartz.job.ScheduledJob;
import com.mm.domain.common.DCornQuartz;
import com.mm.mapper.note.DCornQuartzMapper;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * 描述: Quartz 定时器任务操作
 * <p>
 * 问题1：implements Job 类无法注入mapper Service 问题
 * 原因：newJob传入的对象参数并非Spring注解加载的那个对象。没有通过Spring注解正确的初始化；
 * JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class).withIdentity(jobKey).build();
 *
 * @author: yanglin
 * @Date: 2021-07-27-9:05
 * @Version: 1.0
 */
@Slf4j
@Component
public class SchedulerJobUtil {

    @Resource
    private SchedulerFactoryBean schedulerFactoryBean;

    @Resource
    private DCornQuartzMapper quartzMapper;

    /**
     * 该方法用来启动所有的定时任务
     * 此处可以注入数据库操作，查询出所有的任务配置
     *
     * @throws SchedulerException
     */
    public void scheduleJobs() throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        scheduleJobData(scheduler);
        log.info("Schedule Jobs running");

    }

    public void stop() throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        scheduler.clear();
        log.info("Schedule Jobs stop");
    }

    public void remove(int i) throws SchedulerException {
        String jobKey = "job" + i;
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        boolean deleteJob = scheduler.deleteJob(new JobKey(jobKey, "group1"));
        log.info("Schedule Jobs remove {}, {}", jobKey, deleteJob);
    }

    public void add(int i) throws SchedulerException {
        String jobKey = "job" + i;
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class).withIdentity(jobKey, "group1").build();
        // 每5s执行一次
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("*/5 * * * * ?");
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobKey, "group1").withSchedule(scheduleBuilder).build();
        cronTrigger.getJobDataMap().put("taskId", i);
        scheduler.scheduleJob(jobDetail, cronTrigger);
        log.info("Schedule Jobs add {}, taskId {}", jobKey, i);
    }

    public void addQuartz(DCornQuartz task) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        this.buildQuartz(task, scheduler);
        String key = task.getJobName() + "-" + task.getCornId();
        log.info("Schedule Jobs addQuartz taskId {}", key);
    }

    public void removeQuartz(DCornQuartz task) throws SchedulerException {
        JobKey jobKey = new JobKey(task.getJobName(), task.getJobGroup());
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        scheduler.deleteJob(jobKey);
        String key = task.getJobName() + "-" + task.getCornId();
        log.info("Schedule Jobs removeQuartz taskId {}", key);
    }

    /**
     * 配置Job
     * 此处的任务可以配置可以放到properties或者是放到数据库中
     * 查询数据库;加载所有任务
     *
     * @param scheduler
     * @throws SchedulerException
     */
    private void scheduleJobData(Scheduler scheduler) throws SchedulerException {
        LambdaQueryWrapper<DCornQuartz> queryWrapper = new LambdaQueryWrapper();
        List<DCornQuartz> tasks = quartzMapper.selectList(queryWrapper);
        if (tasks != null && !tasks.isEmpty()) {
            for (DCornQuartz task : tasks) {
                this.buildQuartz(task, scheduler);
            }
        }
        log.info("Corn Quartz num : {}", tasks.size());

    }

    /**
     * 建造定时器
     *
     * @param task
     * @param scheduler
     * @throws SchedulerException
     */
    public void buildQuartz(DCornQuartz task, Scheduler scheduler) throws SchedulerException {
        JobKey jobKey = new JobKey(task.getJobName(), task.getJobGroup());
        JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class).withIdentity(jobKey).build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getQuartzTime());
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(),
                task.getJobGroup()).withSchedule(scheduleBuilder).build();
        String key = task.getJobName() + "-" + task.getCornId();
        cronTrigger.getJobDataMap().put("taskId", key);
        if (!scheduler.checkExists(jobKey)) {
            scheduler.scheduleJob(jobDetail, cronTrigger);
            log.info("buildQuartz taskId: {} quartzTime: {}", key, task.getQuartzTime());
        }
    }
}
